import { _decorator, Component, Node, RigidBody, Vec3, input, Input, EventTouch, RigidBodyComponent, ColliderComponent, ITriggerEvent, director, PhysicsSystem, math, v3, Quat } from 'cc';
import { PlayerJoystick } from './PlayerJoystick';
const { ccclass, property } = _decorator;

@ccclass('PlayerController')
export class PlayerController extends Component {
    @property
    moveSpeed: number = 5; // 移动速度
    
    @property
    rotationSpeed: number = 5; // 旋转速度
    
    @property(PlayerJoystick)
    joystick: PlayerJoystick = null; // 摇杆组件
    
    private _rigidBody: RigidBodyComponent = null; // 刚体组件
    private _collider: ColliderComponent = null; // 碰撞体组件
    private _isColliding: boolean = false; // 是否正在碰撞
    private _collisionNormal: Vec3 = new Vec3(); // 碰撞法线方向

    onLoad() {
        // 获取组件
        this._rigidBody = this.getComponent(RigidBody);
        this._collider = this.getComponent(ColliderComponent);
        
        // 注册碰撞事件
        if (this._collider) {
            this._collider.on('onCollisionEnter', this.onCollisionEnter, this);
            this._collider.on('onCollisionStay', this.onCollisionStay, this);
            this._collider.on('onCollisionExit', this.onCollisionExit, this);
        }
    }

    update(deltaTime: number) {
        // 如果没有摇杆输入或正在碰撞但输入方向不正确，则不移动
        if (!this.joystick.isActive || 
            (this._isColliding && !this.canMoveInDirection(this.joystick.direction))) {
            // 保持位置不变
            this._rigidBody.setLinearVelocity(Vec3.ZERO);
            return;
        }
        
        // 获取摇杆方向
        const direction = this.joystick.direction;
        if (direction.equals(Vec3.ZERO)) return;
        
        // 计算移动速度
        const velocity = direction.multiplyScalar(this.moveSpeed);
        this._rigidBody.setLinearVelocity(velocity);
        
        // 旋转角色朝向移动方向
        this.rotateTowards(direction, deltaTime);
    }

    // 检查是否可以朝某个方向移动
    canMoveInDirection(direction: Vec3): boolean {
        if (!this._isColliding) return true;
        
        // 计算移动方向与碰撞法线的点积
        const dot = Vec3.dot(direction, this._collisionNormal);
        
        // 如果点积大于0，表示方向朝向碰撞体内部，不允许移动
        // 如果点积小于0，表示方向远离碰撞体或平行，允许移动
        return dot < 0;
    }

    // 旋转角色朝向移动方向
    rotateTowards(direction: Vec3, deltaTime: number) {
        // // 计算目标旋转角度
        // const targetAngle = Math.atan2(direction.x, direction.z) * math.RAD2DEG;
        
        // // 当前旋转角度
        // const currentRotation = this.node.eulerAngles.clone();
        
        // // 平滑旋转
        // const newAngle = math.lerp(currentRotation.y, targetAngle, this.rotationSpeed * deltaTime);
        
        // // 应用旋转
        // this.node.setRotationFromEuler(currentRotation.x, newAngle, currentRotation.z);
    }

    // 碰撞开始
    onCollisionEnter(event: ITriggerEvent) {
        // 忽略触发器
        if (!event.otherCollider.isTrigger) {
            this._isColliding = true;
            
            // 计算碰撞法线方向
            Vec3.subtract(this.node.position, event.otherCollider.node.position, this._collisionNormal);
            this._collisionNormal.normalize();
        }
    }

    // 碰撞持续中
    onCollisionStay(event: ITriggerEvent) {
        if (!event.otherCollider.isTrigger) {
            this._isColliding = true;
            
            // 更新碰撞法线方向
            Vec3.subtract(this.node.position, event.otherCollider.node.position, this._collisionNormal);
            this._collisionNormal.normalize();
        }
    }

    // 碰撞结束
    onCollisionExit() {
        this._isColliding = false;
    }
}